package com.qsl.file;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * @Description: 一个线程写，一个线程copy
 * @Author: 博客园@青石路
 * @CreateDate: 2022/9/5 8:52
 **/
public class WriteAndCopyTest {

    private static Thread t1 = null, t2 = null;

    public static void main(String[] args) throws Exception {
        randomAccessTest();
    }

    public static void randomAccessTest() throws Exception {
        String fileName = "D://randomAccess.txt";
        String hello = "hello\r\n";
        String world = "world\r\n";

        // 一个线程写文件
        t1 = new Thread(() -> {
            try {
                RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
                // 预分配文件空间
                raf.setLength(hello.length() + world.length());
                // 先写一部分内容
                raf.write(hello.getBytes("utf-8"));
                //LockSupport.unpark(t2);
                //LockSupport.park();
                TimeUnit.SECONDS.sleep(1);
                raf.write(world.getBytes("utf-8"));
                raf.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "t1");

        // 一个线程拷贝文件
        t2 = new Thread(() -> {
            try {
                // LockSupport.park();
                File src = new File(fileName);
                File dest = new File("E://randomAccess.txt");
                Files.copy(src.toPath(), dest.toPath());
                FileInputStream fileInputStream = new FileInputStream(dest);
                /*System.out.println("dest length = " + dest.length());
                System.out.println("dest size = " + fileInputStream.getChannel().size());
                System.out.println("dest available = " + fileInputStream.available());*/
                System.out.println("拷贝文件MD5 = " + DigestUtils.md5Hex(fileInputStream));
                fileInputStream.close();
                //LockSupport.unpark(t1);
                // TimeUnit.SECONDS.sleep(2);
                fileInputStream = new FileInputStream(src);
                System.out.println("源文件MD5 = " + DigestUtils.md5Hex(fileInputStream));
                fileInputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "t2");
        t1.start();
        t2.start();

    }

    public static void writeAndCopy() throws IOException {
        File src = new File("D:/src.txt");
        File dest = new File("E:/dest.txt");
        src.createNewFile();
        dest.createNewFile();

        t1 = new Thread(() -> {
            try {
                FileOutputStream fos = new FileOutputStream(src, true);
                fos.write("hello\r\n".getBytes("utf-8"));
                fos.flush();
                System.out.println(DigestUtils.md5Hex(new FileInputStream(src)));
                LockSupport.unpark(t2);
                LockSupport.park();
                fos.write("world\r\n".getBytes("utf-8"));
                fos.flush();
                fos.close();
                System.out.println(DigestUtils.md5Hex(new FileInputStream(src)));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "t1");

        t2 = new Thread(() -> {
            try {
                LockSupport.park();
                FileUtils.copyFile(src, dest);
                System.out.println(DigestUtils.md5Hex(new FileInputStream(dest)));
                LockSupport.unpark(t1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "t2");

        t1.start();
        t2.start();
    }
}
